package com.tanhua.sso.service;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tanhua.common.pojo.User;
import com.tanhua.sso.controller.UserController;
import com.tanhua.sso.mapper.UserMapper;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class UserService {
    private static final ObjectMapper MAPPER = new ObjectMapper();
    private static final Logger LOGGER = LoggerFactory.getLogger(UserService.class);
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserController userController;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private HuanXinService huanXinService;

    @Value("${jwt.secret}")
    String secret;

    /**
     * 校验登录
     *
     * @param mobile 手机号
     * @param code 验证码
     * @return 如果信息正确，返回token信息，否则返回null
     */
    public String login(String mobile, String code) {
        // 默认为以注册
        boolean isNew = false;
        String redisKey = "CHECK_CODE_" + mobile;
        String value = redisTemplate.opsForValue().get(redisKey);
        /*if (StringUtils.isEmpty(value)) {
            return null;
        }*/
        // 校验验证码
        if (!StringUtils.equals(value, code)) {
            return null;
        }
        // 验证码正确，删除之前的验证码
        this.redisTemplate.delete(redisKey);

        // 检查是不是第一次登录
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mobile", mobile);
        /*List<User> users = userMapper.selectList(queryWrapper);
        User user = users.get(0);*/
        User user = userMapper.selectOne(queryWrapper);
        if (user == null) {
            // 新用户进行注册
            user = new User();
            user.setMobile(mobile);
            user.setPassword(DigestUtils.md5Hex("123456"));
            userMapper.insert(user);
            isNew = true;
            //注册为环信用户
            huanXinService.userRegister(user.getId());
        }

        // 生成token
        Map<String, Object> claims = new HashMap<>();
        claims.put("mobile", mobile);
        claims.put("id", user.getId());
        String token = Jwts.builder()
                .setClaims(claims) //设置响应数据体
                .signWith(SignatureAlgorithm.HS256, secret) //设置加密方法和加密盐
                .compact();
        //将用户数据写入到redis中
        try {
            String redisTokenKey = "TOKEN_" + token;
            String redisTokenValue = MAPPER.writeValueAsString(user);
            redisTemplate.opsForValue().set(redisTokenKey, redisTokenValue);
        } catch (Exception e) {
            LOGGER.error("存储Token错误", e);
            return null;
        }

        // 发送消息
        try {
            // 发送登录成功的消息
            Map<String, Object> msg = new HashMap<>();
            msg.put("id", user.getId());
            msg.put("mobile", mobile);
            msg.put("date", new Date());
            this.rocketMQTemplate.convertAndSend("tanhua-sso-login", msg);
        } catch (Exception e) {
            LOGGER.error("发送消息错误", e);
        }

        return isNew + "|" + token;
    }

    /**
     * 为其他系统提供根据token来查询用户信息的接口。
     * @param token
     * @return
     */
    public User queryUserByToken(String token){
        try {
            String redisTokenKey = "TOKEN_" + token;
            String cacheData = redisTemplate.opsForValue().get(redisTokenKey);
            if (StringUtils.isEmpty(cacheData)){
                return null;
            }
            // 刷新时间
            redisTemplate.expire(redisTokenKey,1, TimeUnit.HOURS);
            return MAPPER.readValue(cacheData, User.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 更新手机号
     *
     * @param id
     * @param newPhone
     * @return
     */
    public boolean updatePhone(Long id, String newPhone) {
        QueryWrapper<User> query = new QueryWrapper<>();
        query.eq("id",id);
        User user = this.userMapper.selectOne(query);
        if (StringUtils.equals(user.getMobile(),newPhone)){
            return false;
        }

        user = new User();
        user.setId(id);
        user.setMobile(newPhone);
        return this.userMapper.updateById(user) > 0;
    }
}
